/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or ( at your option ) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
aLONG with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
#include "commonheaders.h"

// global:
PLUGINLINK*			pluginLink		= NULL;
HINSTANCE				ghInst				= NULL;
MM_INTERFACE		mmi;
UTF8_INTERFACE	utfi;
LIST_INTERFACE	li;
//XML_API					xi; //for late use

MGLOBAL					myGlobals;

/**
 * Calculates an unique DWORD number from a string.
 * It's the same as used in langpack.
 *
 * @param		szStr	- string to calculate the hash value for
 * @return	the unique id for the szStr
 **/

#if __GNUC__
#define NOINLINEASM
#endif

DWORD hashSetting( LPCSTR szStr )
{
#if defined _M_IX86 && !defined _NUMEGA_BC_FINALCHECK && !defined NOINLINEASM
   __asm 
	 {
      xor   edx,edx
      xor   eax,eax
      mov   esi,szStr
      mov   al,[esi]
      dec   esi
      xor   cl,cl
   lph_top:    //only 4 of 9 instructions in here don't use AL, so optimal pipe use is impossible
      xor   edx,eax
      inc   esi
      and   cl,31
      movzx eax,byte ptr [esi]
      add   cl,5
      test  al,al
      rol   eax,cl      //rol is u-pipe only, but pairable
												//rol doesn't touch z-flag
      jnz   lph_top			//5 clock tick loop. not bad.

      xor   eax,edx
   }
#else
   DWORD hash = 0;
   int i;
   int shift = 0;
   for( i = 0; szStr[i]; i++ ) 
	 {
      hash ^= szStr[i] << shift;
      if ( shift > 24 )
			{
				hash ^= ( szStr[i] >> ( 32 - shift ) ) & 0x7F;
			}
      shift = ( shift + 5 ) & 0x1F;
   }
   return hash;
#endif
}